/**
 * 
 */
package com.rmv.ums;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import com.rmv.ums.configuration.Configuration;
import com.rmv.ums.request.Request;
import com.rmv.ums.response.Response;

/**
 * TODO - toString,equals for all ComparableNode TODO - quitar el alert de
 * condition.check() 
 * TODO - logs 
 * TODO - javadoc
 * TODO - use loader.getResources() to load automatically configuration files
 * 
 * @author Rafael Munoz <rafael.munoz@gmail.com>
 * 
 */
public class FrontEndServlet extends HttpServlet {

	private static final Logger logger = Logger.getLogger(FrontEndServlet.class);

	private static final long serialVersionUID = 1L;

	private static final String LOG4J_CONFIG_PARAM = "config-log4j";
	private static final String DEFAULT_LOG4J_CONFIG_FILE = File.separator + "WEB-INF" + File.separator + "log4j-config.xml";
	private static final String GENERAL_CONFIG_PARAM = "config-general";
	private static final String DEFAULT_GENERAL_CONFIG_FILE = File.separator + "WEB-INF" + File.separator + "ums.properties";
	private static final String CONFIG_PARAM = "config";

	// Initialisation
	public void init() {
		String base = getBasePath();
		configureLog(base);
		loadGeneralConfiguration(base);
		loadConfiguration(base);

	}

	private String getBasePath() {
		String base = getServletContext().getRealPath("/");
		if (!base.endsWith(File.separator)) {
			base = base + File.separator;
		}
		return base;
	}

	private void configureLog(String base) {
		String path = getInitParameter(LOG4J_CONFIG_PARAM);
		if (path == null) {
			path = DEFAULT_LOG4J_CONFIG_FILE;
		} else {
			path = path.replace('/', File.separatorChar);
		}

		System.out.println("Log4j Init:ConfigureAndWatch from config:" + path);
		DOMConfigurator.configureAndWatch(base + path, 30000);
	}

	private void loadGeneralConfiguration(String base) {
		String path = getInitParameter(GENERAL_CONFIG_PARAM);
		if (path == null) {
			path = DEFAULT_GENERAL_CONFIG_FILE;
		} else {
			path = path.replace('/', File.separatorChar);
		}
		Configuration.getInstance().loadConfiguration(base + path);
		logger.info("Universal Mock Server configured from file:" + path);
	}

	private void loadConfiguration(String base) {
		String path = getInitParameter(CONFIG_PARAM);
		if (path == null) {
			throw new RuntimeException("error initialisating server: no config file param found");
		} else {
			path = path.replace('/', File.separatorChar);
		}
		Configuration.getInstance().loadRequests(base + path);
		logger.info("Universal Mock Server: loaded " + Configuration.getInstance().getRequests().size() + " requests from file:" + path);
	}

	// service
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

		Set requests = Configuration.getInstance().getRequests();

		// looking for the correct request
		boolean processed = false;
		for (Iterator iterator = requests.iterator(); iterator.hasNext();) {
			Request request = (Request) iterator.next();
			processed = request.process(req, resp);
			if (processed)
				break;
		}

		if (!processed) {
			logger.error("request doesn't match any of the configured requests");
			Response response = Configuration.getInstance().getUnknownRequestResponse();
			response.process(req, resp);
			return;
		}

	}

}
